package com.mkz.core.zookeeper.util;

import java.util.concurrent.TimeUnit;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessSemaphoreMutex;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.data.Stat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class ZookeeperUtil {
	@Autowired
	private CuratorFramework zkCurator;
	private static InterProcessSemaphoreMutex lock;
	
	//判断节点是否存在：0不存在1存在，9开头的是错误码
	public String checkNodeExist(String absolutePath){
		if(!isValidPath(absolutePath)){
			return "901";
		}
		try {
			Stat st = zkCurator.checkExists().forPath(absolutePath);
			if(null==st){
				return "0";
			}else{
				return "1";
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error("调用checkExists接口抛出异常，错误代码 909！");
			return "909";
		}
	}
	//创建节点-无节点值
	public boolean createNode(String absolutePath){
		if(!isValidPath(absolutePath)){
			return false;
		}
		try {
			String thisNode = zkCurator.create()
					.creatingParentsIfNeeded()
					.withMode(CreateMode.PERSISTENT)
					.withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
					.forPath(absolutePath, "".getBytes());
			log.info("Zookeeper节点 "+thisNode+" 创建成功！");
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			log.error("调用create接口抛出异常，错误代码 909！");
			return false;
		}
	}
	//创建节点-有节点值
	public boolean createNode(String absolutePath, String nodeValue){
		if(!isValidPath(absolutePath)){
			return false;
		}
		try {
			String thisNode = zkCurator.create()
					.creatingParentsIfNeeded()
					.withMode(CreateMode.PERSISTENT)
					.withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
					.forPath(absolutePath, nodeValue.getBytes());
			log.info("Zookeeper节点 "+thisNode+" 创建成功！");
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			log.error("调用create接口抛出异常，错误代码 909！");
			return false;
		}
	}
	//删除节点
	public boolean deleteNode(String absolutePath){
		if(!isValidPath(absolutePath)){
			return false;
		}
		try {
			zkCurator.delete().deletingChildrenIfNeeded().forPath(absolutePath);
			log.info("Zookeeper节点 "+absolutePath+" 删除成功！");
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			log.error("调用create接口抛出异常，错误代码 909！");
			return false;
		}
	}
	//获取排他锁
	public boolean lock(String absolutePath){
		if(!isValidPath(absolutePath)){
			return false;
		}
		try {
			if(null==lock) {
				lock = new InterProcessSemaphoreMutex(zkCurator, absolutePath);
			}
			return lock.acquire(2, TimeUnit.SECONDS);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("获取分布式锁时抛出异常，错误代码 909！");
			return false;
		}
	}
	//获取排他锁
	public void release(){
		try {
			if(null!=lock){
				lock.release();
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error("释放分布式锁时抛出异常，错误代码 909！");
		}
	}
	//判断节点路径是否合法
	public boolean isValidPath(String absolutePath){
		if(StrUtil.isBlank(absolutePath)){
			log.error("传入的路径为空，错误代码 901！");
			return false;
		}
		if(!absolutePath.startsWith("/")){
			log.error("传入的路径必须以'/'开头，错误代码 902！");
			return false;
		}
		if(absolutePath.endsWith("/")){
			log.error("传入的路径不能以'/'结尾，错误代码 903！");
			return false;
		}
		if("/".equals(absolutePath)){
			log.error("传入的路径没有节点，错误代码 904！");
			return false;
		}
		return true;
	}
}
